package com.yilin.commons.util;

import org.springframework.lang.Nullable;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;

public class DateTimeUtil {
    private static String range = "012345679";

    /**
     * 获取时间戳字符串无格式
     */
    public static String getDateTimeByStr(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        return sdf.format(date);
    }

    /**
     * 获取时间戳字符串无格式
     */
    public static String getDateTimeByShortStr(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        return sdf.format(date);
    }

    /**
     * 获取时间戳字符串yyyy-MM-dd
     */
    public static String getDateTimeSpliceStr(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(date);
    }

    //毫秒转时间
    public static String longDateString(long time) {
        Date date = new Date(time);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        date.setTime(time);
        return sdf.format(date);
    }

    /**
     * 获取当前日日期返回
     */
    public static String getDay() {
        SimpleDateFormat formatter;
        formatter = new SimpleDateFormat("d");
        return formatter.format(new Date());
    }

    /**
     * 获取月份
     */
    public static String getMonth() {
        SimpleDateFormat formatter;
        formatter = new SimpleDateFormat("M");
        return formatter.format(new Date());
    }

    /**
     * 将时间转成某天的最大时间
     */
    public static Date maxDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     * 将时间转成某天的最小时间
     */
    public static Date minDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    //毫秒转时间
    public static Date getTimeToDate(long getTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return stringToDate(sdf.format(getTime), null);
    }

    /**
     * 获取年
     */
    public static String getYear() {
        SimpleDateFormat formatter;
        formatter = new SimpleDateFormat("yyyy");
        return formatter.format(new Date());
    }

    /**
     * 取系统当前时间
     */
    public static String getTimeMillis() {
        return String.valueOf(System.currentTimeMillis());
    }

    /**
     * 取系统当前时间:返回只值为如下形式 2002-10-30 20:24:39
     */
    public static String getTime() {
        return dateToString(new Date(), null);
    }

    /**
     * 取系统当前日期:返回只值为如下形式 2002-10-30
     */
    public static String getDate() {
        return dateToString(new Date(), "yyyy-MM-dd");
    }

    /**
     * 将java.util.Date 格式转换为字符串格式'yyyy-MM-dd HH:mm:ss a'(12小时制) 如Sat May 11
     * 17:23:22 CST 2002 to '2002-05-11 05:23:22 下午'
     */
    public static String dateToString(Date time, String format) {
        if (time == null) return null;
        String f = "yyyy-MM-dd HH:mm:ss";
        if (format != null) {
            f = format;
        }
        SimpleDateFormat formatter;
        formatter = new SimpleDateFormat(f);
        String Time = formatter.format(time);
        return Time;
    }

    /**
     * 指定日期加上/减去天数后的日期
     *
     * @param num 正数为加天，负数为减天
     */
    public static Date plusDay(Date date, int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date == null ? new Date() : date);
        calendar.add(Calendar.DATE, num);// num为增加/减去的天数，可以改变的
        return calendar.getTime();
    }

    /**
     * 指定日期加上/减去后的日期
     *
     * @param num    正数为加，负数为减
     * @param format Calendar中的日期，如操作天： format=Calendar.DATE
     */
    public static Date plusDate(Date date, int num, int format) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date == null ? new Date() : date);
        calendar.add(format, num);// num为增加/减去的天数，可以改变的
        return calendar.getTime();
    }
    /**
     * 指定日期加上多少分钟
     * */
    public  static Date  plusHourDate(@Nullable Date date, int minutf){
        // 创建 Calendar 对象，并将当前时间设置为其时间
        if(date==null) date=new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 将当前时间加上 1 分钟
        calendar.add(Calendar.MINUTE, minutf);
        // 获取加上  分钟后的时间
        return  calendar.getTime();

    }


    public static String dateToString(Date time) {
        if (time == null) return null;
        String f = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat formatter;
        formatter = new SimpleDateFormat(f);
        return formatter.format(time);
    }

    public static String dateNo(String startNo) {
        Random random = new Random();
        StringBuilder result = new StringBuilder();
        //要生成几位，就把这里的数字改成几
        for (int i = 0; i < 4; i++) {
            result.append(range.charAt(random.nextInt(range.length())));
        }
        String timeNo = String.valueOf(System.currentTimeMillis());
        if (timeNo.length() > 12) {
            timeNo = timeNo.substring(0, 12);
        }
        if (startNo.length() > 4) {
            startNo = startNo.substring(0, 4);
        }
        return startNo + timeNo + result;
    }

    public  static  Date stringByZNToDate(String strDate){
        DateFormat inputFormat = new SimpleDateFormat("yyyy年MM月dd日", Locale.CHINA);
        DateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            // 将输入日期字符串解析为 Date 对象
            return inputFormat.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace(); // 处理解析异常
        }
        return  null;
    }


    /**
     * 字符串转为日期
     */
    public static Date stringToDate(String date, String format) {
        if (date == null)  return null;
        if (format == null)    format = "yyyy-MM-dd HH:mm:ss";
        if (date.contains("T")) {
            date = date.replace("T", " ");
        }
        format = format.substring(0, date.length());
        SimpleDateFormat dateFormat  = new SimpleDateFormat(format);
        try {
           return dateFormat.parse(date);
        } catch (ParseException e) {
            return null;
        }
    }

    public static void main(String[] args) {
        System.out.println(stringToDate("2023-03-15 14:59:34", null));
    }

    /**
     * 功能描述： 根据出生日期计算年龄 输入参数: @param birthDate 输入参数: @return 异 常： 创 建 人: yico-cj
     * 日 期: 2016年6月3日下午4:52:07 修 改 人: 日 期: 返 回：int
     */
    public static int getAge(Date birthDate) {
        if (birthDate == null)
            throw new RuntimeException("出生日期不能为null");
        int age = 0;
        Date now = new Date();
        SimpleDateFormat format_y = new SimpleDateFormat("yyyy");
        SimpleDateFormat format_M = new SimpleDateFormat("MM");
        String birth_year = format_y.format(birthDate);
        String this_year = format_y.format(now);
        String birth_month = format_M.format(birthDate);
        String this_month = format_M.format(now);
        // 初步，估算
        age = Integer.parseInt(this_year) - Integer.parseInt(birth_year);
        // 如果未到出生月份，则age - 1
        if (this_month.compareTo(birth_month) < 0)
            age -= 1;
        if (age < 0)
            age = 0;
        return age;
    }


    /**
     * 计算两个日期之间相差的天数
     */
    public static double daysZeroBetween(Date before, Date after) {
        Calendar calst = Calendar.getInstance();
        Calendar caled = Calendar.getInstance();
        calst.setTime(before);
        caled.setTime(after);
        // 设置时间为0时
        calst.set(Calendar.HOUR_OF_DAY, 0);
        calst.set(Calendar.MINUTE, 0);
        calst.set(Calendar.SECOND, 0);
        caled.set(Calendar.HOUR_OF_DAY, 0);
        caled.set(Calendar.MINUTE, 0);
        caled.set(Calendar.SECOND, 0);
        // 得到两个日期相差的天数
        return ((caled.getTime().getTime() / 1000d) - (calst.getTime().getTime() / 1000d)) / 3600d / 24d;
    }

    /**
     * 计算两个日期之间相差的天数
     */
    public static double daysVtBetween(Date before, Date after) {
        Calendar calst = Calendar.getInstance();
        Calendar caled = Calendar.getInstance();
        calst.setTime(before);
        caled.setTime(after);
        // 得到两个日期相差的天数
        return ((caled.getTime().getTime() / 1000d) - (calst.getTime().getTime() / 1000d)) / 3600d / 24d;
    }

    /**
     * 计算两个日期之间相差的秒数
     */
    public static int secondBetween(Date before, Date after) {
        Calendar calsBefore = Calendar.getInstance();
        Calendar caleAfter = Calendar.getInstance();
        calsBefore.setTime(before);
        caleAfter.setTime(after);
        // 得到两个日期相差的秒数
        return ((int) (caleAfter.getTime().getTime() / 1000) - (int) (calsBefore.getTime().getTime() / 1000));
    }

    /**
     * 计算两个日期之间相差的秒数
     */
    public static int secondBetween(Long before, Long after) {
        Calendar calsBefore = Calendar.getInstance();
        Calendar caleAfter = Calendar.getInstance();
        calsBefore.setTime(new Date(before));
        caleAfter.setTime(new Date(after));
        // 得到两个日期相差的秒数
        return ((int) (caleAfter.getTime().getTime() / 1000) - (int) (calsBefore.getTime().getTime() / 1000));
    }

    /**
     * 两个时间相差距离多少天多少小时多少分多少秒
     */
    public static String getDistanceTime(String one, String two) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return getDistanceTime(df.parse(one), df.parse(two));
        } catch (ParseException e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 两个时间相差距离多少天多少小时多少分多少秒
     * 前面的减去后面的
     */
    public static String getDistanceTime(Date one, Date two) {

        long time1 = one.getTime();
        long time2 = two.getTime();
        long diff;
        if (time1 < time2) {
            diff = time2 - time1;
        } else {
            diff = time1 - time2;
        }
        return getDistanceTime(diff);
    }

    public static String getDistanceTime(Long diff) {
        long day = 0;
        long hour = 0;
        long min = 0;
        long sec = 0;
        day = diff / (24 * 60 * 60 * 1000);
        hour = (diff / (60 * 60 * 1000) - day * 24);
        min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
        sec = (diff / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);
        StringBuilder buffer = new StringBuilder();
        if (day != 0) {
            buffer.append(day).append("天");
        }
        if (hour != 0) {
            buffer.append(hour).append("小时");
        }
        if (min != 0) {
            buffer.append(min).append("分");
        }
        if (sec != 0) {
            buffer.append(sec).append("秒");
        }
        return buffer.toString();
    }

    /**
     * 获取当前时间的每个月的字符串
     */
    public static List<String> everyMonthStrFmt(Date date) {
        List<String> list = new ArrayList<>();
        Calendar calst = Calendar.getInstance();
        calst.setTime(date);
        int year = calst.get(Calendar.YEAR);
        String month = "0";
        String yearandMonth = "1991-01";
        for (int i = 1; i <= 12; i++) {
            if (i < 10) {
                month = "0" + i;
            } else {
                month = i + "";
            }
            yearandMonth = year + "-" + month;
            list.add(yearandMonth);
        }
        return list;
    }

    /**
     * 获取某个季度的开始时间和结束时间
     * 后面的时间减去签名的时间，返回值可为负数
     */
    public static Date[] getQuarter(Date date) {
        List<Date> dataList = new ArrayList<>();
        Calendar calst = Calendar.getInstance();
        calst.setTime(date);
        Calendar startMonth = Calendar.getInstance();
        Calendar endMonth = Calendar.getInstance();
        int m = calst.get(Calendar.MONTH) + 1;
        if (m >= 1 && m <= 3) {
            startMonth.set(calst.get(Calendar.YEAR), 0, 1, 0, 0, 0);
            endMonth.set(calst.get(Calendar.YEAR), 2, 31, 0, 0, 0);
        } else if (m >= 4 && m <= 6) {
            startMonth.set(calst.get(Calendar.YEAR), 3, 1, 0, 0, 0);
            endMonth.set(calst.get(Calendar.YEAR), 5, 30, 0, 0, 0);
        } else if (m >= 7 && m <= 9) {
            startMonth.set(calst.get(Calendar.YEAR), 6, 1, 0, 0, 0);
            endMonth.set(calst.get(Calendar.YEAR), 8, 30, 0, 0, 0);
        } else {
            startMonth.set(calst.get(Calendar.YEAR), 9, 1, 0, 0, 0);
            endMonth.set(calst.get(Calendar.YEAR), 11, 30, 0, 0, 0);
        }
        return new Date[]{startMonth.getTime(), endMonth.getTime()};
    }


    /**
     * 根据指定的时间字符串，及格式转化成时间毫秒数 默认是yyyy-MM-dd HH:mm:ss
     */
    public static Long getLongtoStringDate(String dataStr, String fomat) throws ParseException {
        if (fomat == null) {
            fomat = "yyyy-MM-dd HH:mm:ss";
        }
        DateFormat dateFormat = new SimpleDateFormat(fomat);
        return dateFormat.parse(dataStr).getTime();
    }

    public static Long getLongtoStringDate(String dataStr) throws ParseException {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.parse(dataStr).getTime();
    }

    /**
     * 获取当天时间 全天范围
     */
    public static Date[] getDayRange(Date date) {
        Calendar calendar1_1 = Calendar.getInstance();
        calendar1_1.setTime(date);
        calendar1_1.set(Calendar.HOUR_OF_DAY, 0);
        calendar1_1.set(Calendar.MINUTE, 0);
        calendar1_1.set(Calendar.SECOND, 0);
        Calendar calendar2_1 = Calendar.getInstance();
        calendar2_1.setTime(date);
        calendar2_1.set(Calendar.HOUR_OF_DAY, 23);
        calendar2_1.set(Calendar.MINUTE, 59);
        calendar2_1.set(Calendar.SECOND, 59);
        return new Date[]{calendar1_1.getTime(), calendar2_1.getTime()};
    }

    /**
     * 获取本周时间 范围
     */
    public static Date[] getWeekRange(Date date) {
        //查询本周
        Calendar calendar1_2 = Calendar.getInstance();
        calendar1_2.setTime(date);
        int dayOfWeek = calendar1_2.get(Calendar.DAY_OF_WEEK);
        calendar1_2.add(Calendar.DATE, -dayOfWeek + 1);
        calendar1_2.set(Calendar.HOUR_OF_DAY, 23);
        calendar1_2.set(Calendar.MINUTE, 59);
        calendar1_2.set(Calendar.SECOND, 59);
        Calendar calendar2_2 = Calendar.getInstance();
        calendar2_2.setTime(date);
        int dayOfWeekEnd = calendar2_2.get(Calendar.DAY_OF_WEEK);
        calendar2_2.add(Calendar.DATE, 7 - dayOfWeekEnd + 1);
        calendar2_2.set(Calendar.HOUR_OF_DAY, 23);
        calendar2_2.set(Calendar.MINUTE, 59);
        calendar2_2.set(Calendar.SECOND, 59);
        return new Date[]{calendar1_2.getTime(), calendar2_2.getTime()};
    }

    /**
     * 获取本月时间 范围
     */
    public static Date[] getMonthRange(Date date) {
        Calendar calendar1_3 = Calendar.getInstance();
        calendar1_3.setTime(date);
        calendar1_3.set(Calendar.DATE, 1);
        calendar1_3.set(Calendar.HOUR_OF_DAY, 0);
        calendar1_3.set(Calendar.MINUTE, 0);
        calendar1_3.set(Calendar.SECOND, 0);
        Calendar calendar2_3 = Calendar.getInstance();
        calendar2_3.setTime(date);
        calendar2_3.set(Calendar.DATE, calendar2_3.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar2_3.set(Calendar.HOUR_OF_DAY, 23);
        calendar2_3.set(Calendar.MINUTE, 59);
        calendar2_3.set(Calendar.SECOND, 59);
        return new Date[]{calendar1_3.getTime(), calendar2_3.getTime()};
    }

    /**
     * 获取本年时间 范围
     */
    public static Date[] getYearRange(Date date) {
        //查询本年
        Calendar calendar1_4 = Calendar.getInstance();
        calendar1_4.setTime(date);
        calendar1_4.set(Calendar.MONTH, 0);
        calendar1_4.set(Calendar.DATE, 1);
        calendar1_4.set(Calendar.HOUR_OF_DAY, 0);
        calendar1_4.set(Calendar.MINUTE, 0);
        calendar1_4.set(Calendar.SECOND, 0);
        Calendar calendar2_4 = Calendar.getInstance();
        calendar2_4.setTime(date);
        calendar2_4.set(Calendar.MONTH, 11);
        calendar2_4.set(Calendar.DATE, calendar2_4.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar2_4.set(Calendar.HOUR_OF_DAY, 23);
        calendar2_4.set(Calendar.MINUTE, 59);
        calendar2_4.set(Calendar.SECOND, 59);
        return new Date[]{calendar1_4.getTime(), calendar2_4.getTime()};
    }

    /*
     * 获取过去12月
     * sort  升序true 降序false
     * current 是否包含当前月 不包含 false 包含 true
     * */
    public static String[] lastMonthsTwelve(boolean sort, boolean current) {
        String[] arr = new String[12];
        int k = 0;
        LocalDate today = LocalDate.now();
        for (long i = 1L; i <= 12L; i++) {
            LocalDate day = today.minusMonths(i - 1);
            if (current) {
                day = today.minusMonths(i);
            }
            String month = day.toString().substring(0, 7);
            arr[k] = month;
            k++;
        }
        if (sort) {
            Arrays.sort(arr);
        }
        return arr;
    }


}